package com.example.demo.lock;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.Locale;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;

/**
 * @author yunda
 * @date 2021/1/20 10:39
 */
@Slf4j
public class ReentrantLockTest {

    private static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            10, 10, 0L,
            TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
            new ThreadFactoryBuilder().setNameFormat("reentrant-lock-test-%d").build());
    private static ReentrantMutexLock lock = new ReentrantMutexLock();
    private static Condition condition = lock.newCondition();

    public static void main(String[] args) {

        pool.submit(()->{
            lock.lock();
            try {
                log.debug("thread-{} acquire lock success", Thread.currentThread().getId());
                log.debug(lock.toString());
                TimeUnit.SECONDS.sleep(2);
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                log.debug("thread-{} release lock", Thread.currentThread().getId());
            }
        });

        pool.submit(()->{
            lock.lock();
            try {
                log.debug("thread-{} acquire lock success", Thread.currentThread().getId());
                log.debug(lock.toString());
                TimeUnit.SECONDS.sleep(2);
                log.debug(String.valueOf(lock.isHeldByCurrentThread()));
                condition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                log.debug("thread-{} release lock", Thread.currentThread().getId());
            }
        });

        pool.shutdown();
    }

}
